<?php

require_once APP_DIR . DS . 'models' . DS . 'logic' . DS . 'exception' . DS . 'badformat.php';
require_once APP_DIR . DS . 'models' . DS . 'logic' . DS . 'exception' . DS . 'nullpointer.php';

define('TYPE',0);
define('IDENTIFIER',1);
define('VALUE',2);

class Action {
    private $name;
    private $returnType;
    private $parameters;

    function  __construct($rawAction = null) {
        $elements = $this->parseAction($rawAction);
        $this->setName($elements['action']);
        $this->setParameters($elements['parameters']);
        if (isset ($elements['returntype'])){
            $this->setReturnType($elements['returntype']);
        }
    }

    public function getName() {
        return $this->name;
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function getReturnType() {
        return $this->returnType;
    }

    public function setReturnType($returntype) {
        $this->returnType = $returntype;
    }

    public function getParameters() {
        return $this->parameters;
    }

    public function setParameters($parameters) {
        $this->parameters = $parameters;
    }

    /**
     *
     * Recupera los elementos de la accion de la cadena
     * formato:
     * returntype:nombre(tipo:parametro1=valor,...,tipo:parametroN=valor)
     * @param String $rawAction
     */
    private function parseAction($rawAction) {
        if (!$rawAction) return;

        if (strpos($rawAction, '(') >= 0){
            $elements = $this->parseSignAction($rawAction);
        }
        else {
            $elements = $this->parseURLAction($rawAction);
        }
        
        return $elements;

        
    }

    private function parseSignAction($raw) {
        if (!$raw) throw new NullPointerException();
        $elements = preg_split('/[:\(,=\)]/', $raw);

        // elimino el espacio vacio
        array_pop($elements);

        if (count($elements) < 1) throw new BadFormatException();

        $out = array();
        $returnType = array_shift($elements);
        $signIdentifier = array_shift($elements);
        $out['action'] = $signIdentifier;
        $out['returntype'] = $returnType;
        
        $parameters = array();
        $type = '';
        $identifier = '';
        foreach ($elements as $pos => $currentElement) {
            $elementType = $pos % 3;
            switch ($elementType) {
                case TYPE:
                    $type = $currentElement;
                    break;

                case IDENTIFIER:
                    $identifier = $currentElement;
                    break;
                case VALUE:
                    $param = new stdClass();
                    $param->type = $type;
                    $param->identifier = $identifier;
                    $param->value = $currentElement;
                    $parameters[] = $param;
                    break;
            }
        }

        // guardo el arreglo de parametros
        // en el arreglo de salida
        $out['parameters'] = $parameters;

        return $out;
    }

    private function parseURLAction($raw) {
        if (!$raw) throw new NullPointerException();
        $out = array();
        $parameters = array();
        $elements = parse_url($raw);

        if (!$elements) throw new BadFormatException();

        $signIdentifier = '';
        $signIdentifier .= (isset ($elements['scheme'])) ? $elements['scheme'].'://' : '';
        $signIdentifier .= (isset ($elements['host'])) ? $elements['host'] : '';
	$signIdentifier .= (isset ($elements['port'])) ? ':'.$elements['port'] : '';
        $signIdentifier .= (isset ($elements['path'])) ? $elements['path'] : '';

        $out['action'] = $signIdentifier;

        $duplas = explode('&', $elements['query']);
        foreach ($duplas as $current) {
            $paramData = explode('=', $current);
            $param = new stdClass();
            $param->identifier = $paramData[0];
            $param->value = $paramData[1];
            $parameters[] = $param;
        }

        $out['parameters'] = $parameters;

        return $out;
    }
}

?>
